/*
 * ContAssignMonitor.java
 * 
 * last update: 30.01.2010 by Vlad Badoiu
 * 
 * author:	Vlad Badoiu(vladbadoiu@gmail.com)
 *
 * Obs:
 */
package engine;

/**
 *  This is a monitor which waits for the rValue to change, and then takes care
 * to modify lValue at the end of the time unit specified by the delay values
 * (by posting a SimpleAssignInstruction).
 * <bold> Note: </bold>only typical delays are used here.
 */
class ContAssignMonitor implements Monitor{

	NameSpace ns;

	LeftValue lValue;
	Expression rValue;
	BitVector prevValue, curValue;

	/**
	 * this will keep the last update instruction, so we can remove it if it becomes obsolete
	 */
	SimpleAssignInstruction lastUpdate;

	Delay3 delays;

	ContAssignMonitor(NameSpace ns, LeftValue lValue,
			Expression rValue, Delay3 delays){
		this.ns = ns;
		xConsole.debug("ContAssignMonitor: " + lValue + " <- " + rValue);
		this.lValue = lValue;
		this.rValue = rValue;
		this.delays = delays;
		lastUpdate = null;
		curValue = prevValue = BitVector.bX();
		rValue.addMonitor(this);
	}

	public synchronized void trigger()
	throws InterpretTimeException
	{
		BitVector curValue  = rValue.evaluate().getBits();
		xConsole.debug("curValue = " + rValue.evaluate().getBits());
		if(!curValue.equals(prevValue)){
			xConsole.trace("triggering continuous assignement: " + lValue.toString() +
					" <<< " + rValue + " (" +  curValue + ")");
			int delay = Wire.computeTransitionDelayFor(prevValue, curValue, delays);
			prevValue = curValue;
			if(lastUpdate != null)lastUpdate.inhibate(); //if the last update is still pending, make it harmless
			Time.addFinisher(delay,
					lastUpdate = new SimpleAssignInstruction(ns, lValue,
							new BitVector(curValue), null));
		}
	}
}




